package comag

import (
	"context"
	"gitee.com/captials-team/ubdframe/src/common/utils"
	"sync"
)

const ContextRunId = "__ID__"
const ContextRunName = "__NAME__"

// ConProcessModelActuator 并发处理模型
// 提供 Add 方法添加需要运行的函数，函数提供 context 变量，监听context的 Done() 确定是否结束处理
// Start 启动方法执行，Stop停止方法执行
// Wait 等到各个方法最终执行结束
type ConProcessModelActuator struct {
	fs     []CoFunc
	ctx    context.Context
	cancel context.CancelFunc
	wg     sync.WaitGroup
}

func NewConProcessModelActuator() *ConProcessModelActuator {
	return &ConProcessModelActuator{}
}

func (c *ConProcessModelActuator) Add(f CoFunc) {
	c.fs = append(c.fs, f)
}

func (c *ConProcessModelActuator) AddRepeat(f CoFunc, num int) {
	for i := 1; i <= num; i++ {
		c.Add(f)
	}
}

func (c *ConProcessModelActuator) Start() error {
	c.ctx, c.cancel = context.WithCancel(context.Background())
	for i, f := range c.fs {
		var tmp = f
		var index = i
		c.wg.Add(1)
		go func() {
			defer c.wg.Done()

			ctx := context.WithValue(c.ctx, ContextRunName, utils.RandLetterFigureCode(6))
			ctx = context.WithValue(ctx, ContextRunId, index)
			tmp(ctx)
		}()
	}
	return nil
}

// Stop Start运行后多次stop都可
func (c *ConProcessModelActuator) Stop() error {
	if c.cancel != nil {
		c.cancel()
	}
	return c.Wait()
}

// Wait 等待执行完成
func (c *ConProcessModelActuator) Wait() error {
	c.wg.Wait()
	return nil
}
